home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / ftp-rl.taz / ftp-rl / ftp / ftp.c.old < prev    next >
Encoding:
Text File  |  1992-10-07  |  30.1 KB  |  1,460 lines

  1. /*
  2.  * Copyright (c) 1985, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)ftp.c    5.36 (Berkeley) 6/29/90";
  22. #endif /* not lint */
  23.  
  24. #include <sys/param.h>
  25. #include <sys/stat.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/socket.h>
  28. #include <sys/time.h>
  29. #include <sys/file.h>
  30.  
  31. #include <netinet/in.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/ip.h>
  34. #include <arpa/ftp.h>
  35. #include <arpa/telnet.h>
  36.  
  37. #include <stdio.h>
  38. #include <signal.h>
  39. #include <errno.h>
  40. #include <netdb.h>
  41. #include <fcntl.h>
  42. #include <pwd.h>
  43. #include <varargs.h>
  44.  
  45. #include "ftp_var.h"
  46. #include "pathnames.h"
  47.  
  48. struct    sockaddr_in hisctladdr;
  49. struct    sockaddr_in data_addr;
  50. int    data = -1;
  51. int    abrtflag = 0;
  52. int    ptflag = 0;
  53. struct    sockaddr_in myctladdr;
  54. uid_t    getuid();
  55. sig_t    lostpeer();
  56. off_t    restart_point = 0;
  57.  
  58. extern char *strerror();
  59. extern int connected, errno;
  60.  
  61. FILE    *cin, *cout;
  62. FILE    *dataconn();
  63.  
  64. char *
  65. hookup(host, port)
  66.     char *host;
  67.     int port;
  68. {
  69.     register struct hostent *hp = 0;
  70.     int s, len, tos;
  71.     static char hostnamebuf[80];
  72.  
  73.     bzero((char *)&hisctladdr, sizeof (hisctladdr));
  74.     hisctladdr.sin_addr.s_addr = inet_addr(host);
  75.     if (hisctladdr.sin_addr.s_addr != -1) {
  76.         hisctladdr.sin_family = AF_INET;
  77.         (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
  78.     } else {
  79.         hp = gethostbyname(host);
  80.         if (hp == NULL) {
  81.             fprintf(stderr, "ftp: %s: ", host);
  82.             herror((char *)NULL);
  83.             code = -1;
  84.             return((char *) 0);
  85.         }
  86.         hisctladdr.sin_family = hp->h_addrtype;
  87.         bcopy(hp->h_addr_list[0],
  88.             (caddr_t)&hisctladdr.sin_addr, hp->h_length);
  89.         (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
  90.     }
  91.     hostname = hostnamebuf;
  92.     s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
  93.     if (s < 0) {
  94.         perror("ftp: socket");
  95.         code = -1;
  96.         return (0);
  97.     }
  98.     hisctladdr.sin_port = port;
  99.     while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
  100.         if (hp && hp->h_addr_list[1]) {
  101.             int oerrno = errno;
  102.             extern char *inet_ntoa();
  103.  
  104.             fprintf(stderr, "ftp: connect to address %s: ",
  105.                 inet_ntoa(hisctladdr.sin_addr));
  106.             errno = oerrno;
  107.             perror((char *) 0);
  108.             hp->h_addr_list++;
  109.             bcopy(hp->h_addr_list[0],
  110.                  (caddr_t)&hisctladdr.sin_addr, hp->h_length);
  111.             fprintf(stdout, "Trying %s...\n",
  112.                 inet_ntoa(hisctladdr.sin_addr));
  113.             (void) close(s);
  114.             s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
  115.             if (s < 0) {
  116.                 perror("ftp: socket");
  117.                 code = -1;
  118.                 return (0);
  119.             }
  120.             continue;
  121.         }
  122.         perror("ftp: connect");
  123.         code = -1;
  124.         goto bad;
  125.     }
  126.     len = sizeof (myctladdr);
  127.     if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
  128.         perror("ftp: getsockname");
  129.         code = -1;
  130.         goto bad;
  131.     }
  132. #ifdef IP_TOS
  133.     tos = IPTOS_LOWDELAY;
  134.     if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
  135.         perror("ftp: setsockopt TOS (ignored)");
  136. #endif
  137.     cin = fdopen(s, "r");
  138.     cout = fdopen(s, "w");
  139.     if (cin == NULL || cout == NULL) {
  140.         fprintf(stderr, "ftp: fdopen failed.\n");
  141.         if (cin)
  142.             (void) fclose(cin);
  143.         if (cout)
  144.             (void) fclose(cout);
  145.         code = -1;
  146.         goto bad;
  147.     }
  148.     if (verbose)
  149.         printf("Connected to %s.\n", hostname);
  150.     if (getreply(0) > 2) {     /* read startup message from server */
  151.         if (cin)
  152.             (void) fclose(cin);
  153.         if (cout)
  154.             (void) fclose(cout);
  155.         code = -1;
  156.         goto bad;
  157.     }
  158. #ifdef SO_OOBINLINE
  159.     {
  160.     int on = 1;
  161.  
  162.     if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
  163.         < 0 && debug) {
  164.             perror("ftp: setsockopt");
  165.         }
  166.     }
  167. #endif /* SO_OOBINLINE */
  168.  
  169.     return (hostname);
  170. bad:
  171.     (void) close(s);
  172.     return ((char *)0);
  173. }
  174.  
  175. login(host)
  176.     char *host;
  177. {
  178.     char tmp[80];
  179.     char *user, *pass, *acct, *getlogin(), *getpass();
  180.     int n, aflag = 0;
  181.  
  182.     user = pass = acct = 0;
  183.     if (ruserpass(host, &user, &pass, &acct) < 0) {
  184.         code = -1;
  185.         return(0);
  186.     }
  187.     while (user == NULL) {
  188.         char *myname = getlogin();
  189.  
  190.         if (myname == NULL) {
  191.             struct passwd *pp = getpwuid(getuid());
  192.  
  193.             if (pp != NULL)
  194.                 myname = pp->pw_name;
  195.         }
  196.         if (myname)
  197.             printf("Name (%s:%s): ", host, myname);
  198.         else
  199.             printf("Name (%s): ", host);
  200.         (void) fgets(tmp, sizeof(tmp) - 1, stdin);
  201.         tmp[strlen(tmp) - 1] = '\0';
  202.         if (*tmp == '\0')
  203.             user = myname;
  204.         else
  205.             user = tmp;
  206.     }
  207.     n = command("USER %s", user);
  208.     if (n == CONTINUE) {
  209.         if (pass == NULL)
  210.             pass = getpass("Password:");
  211.         n = command("PASS %s", pass);
  212.     }
  213.     if (n == CONTINUE) {
  214.         aflag++;
  215.         acct = getpass("Account:");
  216.         n = command("ACCT %s", acct);
  217.     }
  218.     if (n != COMPLETE) {
  219.         fprintf(stderr, "Login failed.\n");
  220.         return (0);
  221.     }
  222.     if (!aflag && acct != NULL)
  223.         (void) command("ACCT %s", acct);
  224.     if (proxy)
  225.         return(1);
  226.     for (n = 0; n < macnum; ++n) {
  227.         if (!strcmp("init", macros[n].mac_name)) {
  228.             (void) strcpy(line, "$init");
  229.             makeargv();
  230.             domacro(margc, margv);
  231.             break;
  232.         }
  233.     }
  234.     return (1);
  235. }
  236.  
  237. void
  238. cmdabort()
  239. {
  240.     extern jmp_buf ptabort;
  241.  
  242.     printf("\n");
  243.     (void) fflush(stdout);
  244.     abrtflag++;
  245.     if (ptflag)
  246.         longjmp(ptabort,1);
  247. }
  248.  
  249. /*VARARGS*/
  250. command(va_alist)
  251. va_dcl
  252. {
  253.     va_list ap;
  254.     char *fmt;
  255.     int r;
  256.     sig_t oldintr;
  257.     void cmdabort();
  258.  
  259.     abrtflag = 0;
  260.     if (debug) {
  261.         printf("---> ");
  262.         va_start(ap);
  263.         fmt = va_arg(ap, char *);
  264.         if (strncmp("PASS ", fmt, 5) == 0)
  265.             printf("PASS XXXX");
  266.         else 
  267.             vfprintf(stdout, fmt, ap);
  268.         va_end(ap);
  269.         printf("\n");
  270.         (void) fflush(stdout);
  271.     }
  272.     if (cout == NULL) {
  273.         perror ("No control connection for command");
  274.         code = -1;
  275.         return (0);
  276.     }
  277.     oldintr = signal(SIGINT, cmdabort);
  278.     va_start(ap);
  279.     fmt = va_arg(ap, char *);
  280.     vfprintf(cout, fmt, ap);
  281.     va_end(ap);
  282.     fprintf(cout, "\r\n");
  283.     (void) fflush(cout);
  284.     cpend = 1;
  285.     r = getreply(!strcmp(fmt, "QUIT"));
  286.     if (abrtflag && oldintr != SIG_IGN)
  287. /*        (*oldintr)();*/
  288.     signal(SIGINT, cmdabort);
  289.     (void) signal(SIGINT, oldintr);
  290.     return(r);
  291. }
  292.  
  293. char reply_string[BUFSIZ];        /* last line of previous reply */
  294.  
  295. #include <ctype.h>
  296.  
  297. getreply(expecteof)
  298.     int expecteof;
  299. {
  300.     register int c, n;
  301.     register int dig;
  302.     register char *cp;
  303.     int originalcode = 0, continuation = 0;
  304.     sig_t oldintr;
  305.     int pflag = 0;
  306.     char *pt = pasv;
  307.     void cmdabort();
  308.  
  309.     oldintr = signal(SIGINT, cmdabort);
  310.     for (;;) {
  311.         dig = n = code = 0;
  312.         cp = reply_string;
  313.         while ((c = getc(cin)) != '\n') {
  314.             if (c == IAC) {     /* handle telnet commands */
  315.                 switch (c = getc(cin)) {
  316.                 case WILL:
  317.                 case WONT:
  318.                     c = getc(cin);
  319.                     fprintf(cout, "%c%c%c", IAC, DONT, c);
  320.                     (void) fflush(cout);
  321.                     break;
  322.                 case DO:
  323.                 case DONT:
  324.                     c = getc(cin);
  325.                     fprintf(cout, "%c%c%c", IAC, WONT, c);
  326.                     (void) fflush(cout);
  327.                     break;
  328.                 default:
  329.                     break;
  330.                 }
  331.                 continue;
  332.             }
  333.             dig++;
  334.             if (c == EOF) {
  335.                 if (expecteof) {
  336.                     (void) signal(SIGINT,oldintr);
  337.                     code = 221;
  338.                     return (0);
  339.                 }
  340.                 lostpeer();
  341.                 if (verbose) {
  342.                     printf("421 Service not available, remote server has closed connection\n");
  343.                     (void) fflush(stdout);
  344.                 }
  345.                 code = 421;
  346.                 return(4);
  347.             }
  348.             if (c != '\r' && (verbose > 0 ||
  349.                 (verbose > -1 && n == '5' && dig > 4))) {
  350.                 if (proxflag &&
  351.                    (dig == 1 || dig == 5 && verbose == 0))
  352.                     printf("%s:",hostname);
  353.                 (void) putchar(c);
  354.             }
  355.             if (dig < 4 && isdigit(c))
  356.                 code = code * 10 + (c - '0');
  357.             if (!pflag && code == 227)
  358.                 pflag = 1;
  359.             if (dig > 4 && pflag == 1 && isdigit(c))
  360.                 pflag = 2;
  361.             if (pflag == 2) {
  362.                 if (c != '\r' && c != ')')
  363.                     *pt++ = c;
  364.                 else {
  365.                     *pt = '\0';
  366.                     pflag = 3;
  367.                 }
  368.             }
  369.             if (dig == 4 && c == '-') {
  370.                 if (continuation)
  371.                     code = 0;
  372.                 continuation++;
  373.             }
  374.             if (n == 0)
  375.                 n = c;
  376.             if (cp < &reply_string[sizeof(reply_string) - 1])
  377.                 *cp++ = c;
  378.         }
  379.         if (verbose > 0 || verbose > -1 && n == '5') {
  380.             (void) putchar(c);
  381.             (void) fflush (stdout);
  382.         }
  383.         if (continuation && code != originalcode) {
  384.             if (originalcode == 0)
  385.                 originalcode = code;
  386.             continue;
  387.         }
  388.         *cp = '\0';
  389.         if (n != '1')
  390.             cpend = 0;
  391.         (void) signal(SIGINT,oldintr);
  392.         if (code == 421 || originalcode == 421)
  393.             lostpeer();
  394.         if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
  395. /*            (*oldintr)();*/
  396.             signal(SIGINT, cmdabort);
  397.         return (n - '0');
  398.     }
  399. }
  400.  
  401. empty(mask, sec)
  402.     /*struct*/ fd_set *mask;
  403.     int sec;
  404. {
  405.     struct timeval t;
  406.  
  407.     t.tv_sec = (long) sec;
  408.     t.tv_usec = 0;
  409.     return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
  410. }
  411.  
  412. jmp_buf    sendabort;
  413.  
  414. void
  415. abortsend()
  416. {
  417.  
  418.     mflag = 0;
  419.     abrtflag = 0;
  420.     printf("\nsend aborted\nwaiting for remote to finish abort\n");
  421.     (void) fflush(stdout);
  422.     longjmp(sendabort, 1);
  423. }
  424.  
  425. #define HASHBYTES 1024
  426.  
  427. sendrequest(cmd, local, remote, printnames)
  428.     char *cmd, *local, *remote;
  429.     int printnames;
  430. {
  431.     struct stat st;
  432.     struct timeval start, stop;
  433.     register int c, d;
  434.     FILE *fin, *dout = 0, *popen();
  435.     int (*closefunc)(), pclose(), fclose();
  436.     sig_t oldintr, oldintp;
  437.     long bytes = 0, hashbytes = HASHBYTES;
  438.     char *lmode, buf[BUFSIZ], *bufp;
  439.     void abortsend();
  440.  
  441.     if (verbose && printnames) {
  442.         if (local && *local != '-')
  443.             printf("local: %s ", local);
  444.         if (remote)
  445.             printf("remote: %s\n", remote);
  446.     }
  447.     if (proxy) {
  448.         proxtrans(cmd, local, remote);
  449.         return;
  450.     }
  451.     if (curtype != type)
  452.         changetype(type, 0);
  453.     closefunc = NULL;
  454.     oldintr = NULL;
  455.     oldintp = NULL;
  456.     lmode = "w";
  457.     if (setjmp(sendabort)) {
  458.         while (cpend) {
  459.             (void) getreply(0);
  460.         }
  461.         if (data >= 0) {
  462.             (void) close(data);
  463.             data = -1;
  464.         }
  465.         if (oldintr)
  466.             (void) signal(SIGINT,oldintr);
  467.         if (oldintp)
  468.             (void) signal(SIGPIPE,oldintp);
  469.         code = -1;
  470.         return;
  471.     }
  472.     oldintr = signal(SIGINT, abortsend);
  473.     if (strcmp(local, "-") == 0)
  474.         fin = stdin;
  475.     else if (*local == '|') {
  476.         oldintp = signal(SIGPIPE,SIG_IGN);
  477.         fin = popen(local + 1, "r");
  478.         if (fin == NULL) {
  479.             perror(local + 1);
  480.             (void) signal(SIGINT, oldintr);
  481.             (void) signal(SIGPIPE, oldintp);
  482.             code = -1;
  483.             return;
  484.         }
  485.         closefunc = pclose;
  486.     } else {
  487.         fin = fopen(local, "r");
  488.         if (fin == NULL) {
  489.             fprintf(stderr, "local: %s: %s\n", local,
  490.                 strerror(errno));
  491.             (void) signal(SIGINT, oldintr);
  492.             code = -1;
  493.             return;
  494.         }
  495.         closefunc = fclose;
  496.         if (fstat(fileno(fin), &st) < 0 ||
  497.             (st.st_mode&S_IFMT) != S_IFREG) {
  498.             fprintf(stdout, "%s: not a plain file.\n", local);
  499.             (void) signal(SIGINT, oldintr);
  500.             fclose(fin);
  501.             code = -1;
  502.             return;
  503.         }
  504.     }
  505.     if (initconn()) {
  506.         (void) signal(SIGINT, oldintr);
  507.         if (oldintp)
  508.             (void) signal(SIGPIPE, oldintp);
  509.         code = -1;
  510.         if (closefunc != NULL)
  511.             (*closefunc)(fin);
  512.         return;
  513.     }
  514.     if (setjmp(sendabort))
  515.         goto abort;
  516.  
  517.     if (restart_point &&
  518.         (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
  519.         if (fseek(fin, (long) restart_point, 0) < 0) {
  520.             fprintf(stderr, "local: %s: %s\n", local,
  521.                 strerror(errno));
  522.             restart_point = 0;
  523.             if (closefunc != NULL)
  524.                 (*closefunc)(fin);
  525.             return;
  526.         }
  527.         if (command("REST %ld", (long) restart_point)
  528.             != CONTINUE) {
  529.             restart_point = 0;
  530.             if (closefunc != NULL)
  531.                 (*closefunc)(fin);
  532.             return;
  533.         }
  534.         restart_point = 0;
  535.         lmode = "r+w";
  536.     }
  537.     if (remote) {
  538.         if (command("%s %s", cmd, remote) != PRELIM) {
  539.             (void) signal(SIGINT, oldintr);
  540.             if (oldintp)
  541.                 (void) signal(SIGPIPE, oldintp);
  542.             if (closefunc != NULL)
  543.                 (*closefunc)(fin);
  544.             return;
  545.         }
  546.     } else
  547.         if (command("%s", cmd) != PRELIM) {
  548.             (void) signal(SIGINT, oldintr);
  549.             if (oldintp)
  550.                 (void) signal(SIGPIPE, oldintp);
  551.             if (closefunc != NULL)
  552.                 (*closefunc)(fin);
  553.             return;
  554.         }
  555.     dout = dataconn(lmode);
  556.     if (dout == NULL)
  557.         goto abort;
  558.     (void) gettimeofday(&start, (struct timezone *)0);
  559.     oldintp = signal(SIGPIPE, SIG_IGN);
  560.     switch (curtype) {
  561.  
  562.     case TYPE_I:
  563.     case TYPE_L:
  564.         errno = d = 0;
  565.         while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
  566.             bytes += c;
  567.             for (bufp = buf; c > 0; c -= d, bufp += d)
  568.                 if ((d = write(fileno(dout), bufp, c)) <= 0)
  569.                     break;
  570.             if (hash) {
  571.                 while (bytes >= hashbytes) {
  572.                     (void) putchar('#');
  573.                     hashbytes += HASHBYTES;
  574.                 }
  575.                 (void) fflush(stdout);
  576.             }
  577.         }
  578.         if (hash && bytes > 0) {
  579.             if (bytes < HASHBYTES)
  580.                 (void) putchar('#');
  581.             (void) putchar('\n');
  582.             (void) fflush(stdout);
  583.         }
  584.         if (c < 0)
  585.             fprintf(stderr, "local: %s: %s\n", local,
  586.                 strerror(errno));
  587.         if (d <= 0) {
  588.             if (d == 0)
  589.                 fprintf(stderr, "netout: write returned 0?\n");
  590.             else if (errno != EPIPE) 
  591.                 perror("netout");
  592.             bytes = -1;
  593.         }
  594.         break;
  595.  
  596.     case TYPE_A:
  597.         while ((c = getc(fin)) != EOF) {
  598.             if (c == '\n') {
  599.                 while (hash && (bytes >= hashbytes)) {
  600.                     (void) putchar('#');
  601.                     (void) fflush(stdout);
  602.                     hashbytes += HASHBYTES;
  603.                 }
  604.                 if (ferror(dout))
  605.                     break;
  606.                 (void) putc('\r', dout);
  607.                 bytes++;
  608.             }
  609.             (void) putc(c, dout);
  610.             bytes++;
  611.     /*        if (c == '\r') {                  */
  612.     /*        (void)    putc('\0', dout);  /* this violates rfc */
  613.     /*            bytes++;                */
  614.     /*        }                                      */    
  615.         }
  616.         if (hash) {
  617.             if (bytes < hashbytes)
  618.                 (void) putchar('#');
  619.             (void) putchar('\n');
  620.             (void) fflush(stdout);
  621.         }
  622.         if (ferror(fin))
  623.             fprintf(stderr, "local: %s: %s\n", local,
  624.                 strerror(errno));
  625.         if (ferror(dout)) {
  626.             if (errno != EPIPE)
  627.                 perror("netout");
  628.             bytes = -1;
  629.         }
  630.         break;
  631.     }
  632.     (void) gettimeofday(&stop, (struct timezone *)0);
  633.     if (closefunc != NULL)
  634.         (*closefunc)(fin);
  635.     (void) fclose(dout);
  636.     (void) getreply(0);
  637.     (void) signal(SIGINT, oldintr);
  638.     if (oldintp)
  639.         (void) signal(SIGPIPE, oldintp);
  640.     if (bytes > 0)
  641.         ptransfer("sent", bytes, &start, &stop);
  642.     return;
  643. abort:
  644.     (void) gettimeofday(&stop, (struct timezone *)0);
  645.     (void) signal(SIGINT, oldintr);
  646.     if (oldintp)
  647.         (void) signal(SIGPIPE, oldintp);
  648.     if (!cpend) {
  649.         code = -1;
  650.         return;
  651.     }
  652.     if (data >= 0) {
  653.         (void) close(data);
  654.         data = -1;
  655.     }
  656.     if (dout)
  657.         (void) fclose(dout);
  658.     (void) getreply(0);
  659.     code = -1;
  660.     if (closefunc != NULL && fin != NULL)
  661.         (*closefunc)(fin);
  662.     if (bytes > 0)
  663.         ptransfer("sent", bytes, &start, &stop);
  664. }
  665.  
  666. jmp_buf    recvabort;
  667.  
  668. void
  669. abortrecv()
  670. {
  671.  
  672.     mflag = 0;
  673.     abrtflag = 0;
  674.     printf("\nreceive aborted\nwaiting for remote to finish abort\n");
  675.     (void) fflush(stdout);
  676.     longjmp(recvabort, 1);
  677. }
  678.  
  679. recvrequest(cmd, local, remote, lmode, printnames)
  680.     char *cmd, *local, *remote, *lmode;
  681. {
  682.     FILE *fout, *din = 0, *popen();
  683.     int (*closefunc)(), pclose(), fclose();
  684.     sig_t oldintr, oldintp;
  685.     int is_retr, tcrflag, bare_lfs = 0;
  686.     char *gunique();
  687.     static int bufsize;
  688.     static char *buf;
  689.     long bytes = 0, hashbytes = HASHBYTES;
  690.     register int c, d;
  691.     struct timeval start, stop;
  692.     struct stat st;
  693.     off_t lseek();
  694.     void abortrecv();
  695.     char *malloc();
  696.  
  697.     is_retr = strcmp(cmd, "RETR") == 0;
  698.     if (is_retr && verbose && printnames) {
  699.         if (local && *local != '-')
  700.             printf("local: %s ", local);
  701.         if (remote)
  702.             printf("remote: %s\n", remote);
  703.     }
  704.     if (proxy && is_retr) {
  705.         proxtrans(cmd, local, remote);
  706.         return;
  707.     }
  708.     closefunc = NULL;
  709.     oldintr = NULL;
  710.     oldintp = NULL;
  711.     tcrflag = !crflag && is_retr;
  712.     if (setjmp(recvabort)) {
  713.         while (cpend) {
  714.             (void) getreply(0);
  715.         }
  716.         if (data >= 0) {
  717.             (void) close(data);
  718.             data = -1;
  719.         }
  720.         if (oldintr)
  721.             (void) signal(SIGINT, oldintr);
  722.         code = -1;
  723.         return;
  724.     }
  725.     oldintr = signal(SIGINT, abortrecv);
  726.     if (strcmp(local, "-") && *local != '|') {
  727.         if (access(local, 2) < 0) {
  728.             char *dir = rindex(local, '/');
  729.  
  730.             if (errno != ENOENT && errno != EACCES) {
  731.                 fprintf(stderr, "local: %s: %s\n", local,
  732.                     strerror(errno));
  733.                 (void) signal(SIGINT, oldintr);
  734.                 code = -1;
  735.                 return;
  736.             }
  737.             if (dir != NULL)
  738.                 *dir = 0;
  739.             d = access(dir ? local : ".", 2);
  740.             if (dir != NULL)
  741.                 *dir = '/';
  742.             if (d < 0) {
  743.                 fprintf(stderr, "local: %s: %s\n", local,
  744.                     strerror(errno));
  745.                 (void) signal(SIGINT, oldintr);
  746.                 code = -1;
  747.                 return;
  748.             }
  749.             if (!runique && errno == EACCES &&
  750.                 chmod(local, 0600) < 0) {
  751.                 fprintf(stderr, "local: %s: %s\n", local,
  752.                     strerror(errno));
  753.                 (void) signal(SIGINT, oldintr);
  754.                 (void) signal(SIGINT, oldintr);
  755.                 code = -1;
  756.                 return;
  757.             }
  758.             if (runique && errno == EACCES &&
  759.                (local = gunique(local)) == NULL) {
  760.                 (void) signal(SIGINT, oldintr);
  761.                 code = -1;
  762.                 return;
  763.             }
  764.         }
  765.         else if (runique && (local = gunique(local)) == NULL) {
  766.             (void) signal(SIGINT, oldintr);
  767.             code = -1;
  768.             return;
  769.         }
  770.     }
  771.     if (!is_retr) {
  772.         if (curtype != TYPE_A)
  773.             changetype(TYPE_A, 0);
  774.     } else if (curtype != type)
  775.         changetype(type, 0);
  776.     if (initconn()) {
  777.         (void) signal(SIGINT, oldintr);
  778.         code = -1;
  779.         return;
  780.     }
  781.     if (setjmp(recvabort))
  782.         goto abort;
  783.     if (is_retr && restart_point &&
  784.         command("REST %ld", (long) restart_point) != CONTINUE)
  785.         return;
  786.     if (remote) {
  787.         if (command("%s %s", cmd, remote) != PRELIM) {
  788.             (void) signal(SIGINT, oldintr);
  789.             return;
  790.         }
  791.     } else {
  792.         if (command("%s", cmd) != PRELIM) {
  793.             (void) signal(SIGINT, oldintr);
  794.             return;
  795.         }
  796.     }
  797.     din = dataconn("r");
  798.     if (din == NULL)
  799.         goto abort;
  800.     if (strcmp(local, "-") == 0)
  801.         fout = stdout;
  802.     else if (*local == '|') {
  803.         oldintp = signal(SIGPIPE, SIG_IGN);
  804.         fout = popen(local + 1, "w");
  805.         if (fout == NULL) {
  806.             perror(local+1);
  807.             goto abort;
  808.         }
  809.         closefunc = pclose;
  810.     } else {
  811.         fout = fopen(local, lmode);
  812.         if (fout == NULL) {
  813.             fprintf(stderr, "local: %s: %s\n", local,
  814.                 strerror(errno));
  815.             goto abort;
  816.         }
  817.         closefunc = fclose;
  818.     }
  819.     if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
  820.         st.st_blksize = BUFSIZ;
  821.     if (st.st_blksize > bufsize) {
  822.         if (buf)
  823.             (void) free(buf);
  824.         buf = malloc((unsigned)st.st_blksize);
  825.         if (buf == NULL) {
  826.             perror("malloc");
  827.             bufsize = 0;
  828.             goto abort;
  829.         }
  830.         bufsize = st.st_blksize;
  831.     }
  832.     (void) gettimeofday(&start, (struct timezone *)0);
  833.     switch (curtype) {
  834.  
  835.     case TYPE_I:
  836.     case TYPE_L:
  837.         if (restart_point &&
  838.             lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
  839.             fprintf(stderr, "local: %s: %s\n", local,
  840.                 strerror(errno));
  841.             if (closefunc != NULL)
  842.                 (*closefunc)(fout);
  843.             return;
  844.         }
  845.         errno = d = 0;
  846.         while ((c = read(fileno(din), buf, bufsize)) > 0) {
  847.             if ((d = write(fileno(fout), buf, c)) != c)
  848.                 break;
  849.             bytes += c;
  850.             if (hash) {
  851.                 while (bytes >= hashbytes) {
  852.                     (void) putchar('#');
  853.                     hashbytes += HASHBYTES;
  854.                 }
  855.                 (void) fflush(stdout);
  856.             }
  857.         }
  858.         if (hash && bytes > 0) {
  859.             if (bytes < HASHBYTES)
  860.                 (void) putchar('#');
  861.             (void) putchar('\n');
  862.             (void) fflush(stdout);
  863.         }
  864.         if (c < 0) {
  865.             if (errno != EPIPE)
  866.                 perror("netin");
  867.             bytes = -1;
  868.         }
  869.         if (d < c) {
  870.             if (d < 0)
  871.                 fprintf(stderr, "local: %s: %s\n", local,
  872.                     strerror(errno));
  873.             else
  874.                 fprintf(stderr, "%s: short write\n", local);
  875.         }
  876.         break;
  877.  
  878.     case TYPE_A:
  879.         if (restart_point) {
  880.             register int i, n, ch;
  881.  
  882.             if (fseek(fout, 0L, L_SET) < 0)
  883.                 goto done;
  884.             n = restart_point;
  885.             for (i = 0; i++ < n;) {
  886.                 if ((ch = getc(fout)) == EOF)
  887.                     goto done;
  888.                 if (ch == '\n')
  889.                     i++;
  890.             }
  891.             if (fseek(fout, 0L, L_INCR) < 0) {
  892. done:
  893.                 fprintf(stderr, "local: %s: %s\n", local,
  894.                     strerror(errno));
  895.                 if (closefunc != NULL)
  896.                     (*closefunc)(fout);
  897.                 return;
  898.             }
  899.         }
  900.         while ((c = getc(din)) != EOF) {
  901.             if (c == '\n')
  902.                 bare_lfs++;
  903.             while (c == '\r') {
  904.                 while (hash && (bytes >= hashbytes)) {
  905.                     (void) putchar('#');
  906.                     (void) fflush(stdout);
  907.                     hashbytes += HASHBYTES;
  908.                 }
  909.                 bytes++;
  910.                 if ((c = getc(din)) != '\n' || tcrflag) {
  911.                     if (ferror(fout))
  912.                         goto break2;
  913.                     (void) putc('\r', fout);
  914.                     if (c == '\0') {
  915.                         bytes++;
  916.                         goto contin2;
  917.                     }
  918.                     if (c == EOF)
  919.                         goto contin2;
  920.                 }
  921.             }
  922.             (void) putc(c, fout);
  923.             bytes++;
  924.     contin2:    ;
  925.         }
  926. break2:
  927.         if (bare_lfs) {
  928.             printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
  929.             printf("File may not have transferred correctly.\n");
  930.         }
  931.         if (hash) {
  932.             if (bytes < hashbytes)
  933.                 (void) putchar('#');
  934.             (void) putchar('\n');
  935.             (void) fflush(stdout);
  936.         }
  937.         if (ferror(din)) {
  938.             if (errno != EPIPE)
  939.                 perror("netin");
  940.             bytes = -1;
  941.         }
  942.         if (ferror(fout))
  943.             fprintf(stderr, "local: %s: %s\n", local,
  944.                 strerror(errno));
  945.         break;
  946.     }
  947.     if (closefunc != NULL)
  948.         (*closefunc)(fout);
  949.     (void) signal(SIGINT, oldintr);
  950.     if (oldintp)
  951.         (void) signal(SIGPIPE, oldintp);
  952.     (void) gettimeofday(&stop, (struct timezone *)0);
  953.     (void) fclose(din);
  954.     (void) getreply(0);
  955.     if (bytes > 0 && is_retr)
  956.         ptransfer("received", bytes, &start, &stop);
  957.     return;
  958. abort:
  959.  
  960. /* abort using RFC959 recommended IP,SYNC sequence  */
  961.  
  962.     (void) gettimeofday(&stop, (struct timezone *)0);
  963.     if (oldintp)
  964.         (void) signal(SIGPIPE, oldintr);
  965.     (void) signal(SIGINT, SIG_IGN);
  966.     if (!cpend) {
  967.         code = -1;
  968.         (void) signal(SIGINT, oldintr);
  969.         return;
  970.     }
  971.  
  972.     abort_remote(din);
  973.     code = -1;
  974.     if (data >= 0) {
  975.         (void) close(data);
  976.         data = -1;
  977.     }
  978.     if (closefunc != NULL && fout != NULL)
  979.         (*closefunc)(fout);
  980.     if (din)
  981.         (void) fclose(din);
  982.     if (bytes > 0)
  983.         ptransfer("received", bytes, &start, &stop);
  984.     (void) signal(SIGINT, oldintr);
  985. }
  986.  
  987. /*
  988.  * Need to start a listen on the data channel before we send the command,
  989.  * otherwise the server's connect may fail.
  990.  */
  991. initconn()
  992. {
  993.     register char *p, *a;
  994.     int result, len, tmpno = 0;
  995.     int on = 1;
  996.  
  997. noport:
  998.     data_addr = myctladdr;
  999.     if (sendport)
  1000.         data_addr.sin_port = 0;    /* let system pick one */ 
  1001.     if (data != -1)
  1002.         (void) close(data);
  1003.     data = socket(AF_INET, SOCK_STREAM, 0);
  1004.     if (data < 0) {
  1005.         perror("ftp: socket");
  1006.         if (tmpno)
  1007.             sendport = 1;
  1008.         return (1);
  1009.     }
  1010.     if (!sendport)
  1011.         if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
  1012.             perror("ftp: setsockopt (reuse address)");
  1013.             goto bad;
  1014.         }
  1015.     if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
  1016.         perror("ftp: bind");
  1017.         goto bad;
  1018.     }
  1019.     if (options & SO_DEBUG &&
  1020.         setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
  1021.         perror("ftp: setsockopt (ignored)");
  1022.     len = sizeof (data_addr);
  1023.     if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
  1024.         perror("ftp: getsockname");
  1025.         goto bad;
  1026.     }
  1027.     if (listen(data, 1) < 0)
  1028.         perror("ftp: listen");
  1029.     if (sendport) {
  1030.         a = (char *)&data_addr.sin_addr;
  1031.         p = (char *)&data_addr.sin_port;
  1032. #define    UC(b)    (((int)b)&0xff)
  1033.         result =
  1034.             command("PORT %d,%d,%d,%d,%d,%d",
  1035.               UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
  1036.               UC(p[0]), UC(p[1]));
  1037.         if (result == ERROR && sendport == -1) {
  1038.             sendport = 0;
  1039.             tmpno = 1;
  1040.             goto noport;
  1041.         }
  1042.         return (result != COMPLETE);
  1043.     }
  1044.     if (tmpno)
  1045.         sendport = 1;
  1046. #ifdef IP_TOS
  1047.     on = IPTOS_THROUGHPUT;
  1048.     if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
  1049.         perror("ftp: setsockopt TOS (ignored)");
  1050. #endif
  1051.     return (0);
  1052. bad:
  1053.     (void) close(data), data = -1;
  1054.     if (tmpno)
  1055.         sendport = 1;
  1056.     return (1);
  1057. }
  1058.  
  1059. FILE *
  1060. dataconn(lmode)
  1061.     char *lmode;
  1062. {
  1063.     struct sockaddr_in from;
  1064.     int s, fromlen = sizeof (from), tos;
  1065.  
  1066.     s = accept(data, (struct sockaddr *) &from, &fromlen);
  1067.     if (s < 0) {
  1068.         perror("ftp: accept");
  1069.         (void) close(data), data = -1;
  1070.         return (NULL);
  1071.     }
  1072.     (void) close(data);
  1073.     data = s;
  1074. #ifdef IP_TOS
  1075.     tos = IPTOS_THROUGHPUT;
  1076.     if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
  1077.         perror("ftp: setsockopt TOS (ignored)");
  1078. #endif
  1079.     return (fdopen(data, lmode));
  1080. }
  1081.  
  1082. ptransfer(direction, bytes, t0, t1)
  1083.     char *direction;
  1084.     long bytes;
  1085.     struct timeval *t0, *t1;
  1086. {
  1087.     struct timeval td;
  1088.     float s, bs;
  1089.  
  1090.     if (verbose) {
  1091.         tvsub(&td, t1, t0);
  1092.         s = td.tv_sec + (td.tv_usec / 1000000.);
  1093. #define    nz(x)    ((x) == 0 ? 1 : (x))
  1094.         bs = bytes / nz(s);
  1095.         printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
  1096.             bytes, direction, s, bs / 1024.);
  1097.     }
  1098. }
  1099.  
  1100. /*tvadd(tsum, t0)
  1101.     struct timeval *tsum, *t0;
  1102. {
  1103.  
  1104.     tsum->tv_sec += t0->tv_sec;
  1105.     tsum->tv_usec += t0->tv_usec;
  1106.     if (tsum->tv_usec > 1000000)
  1107.         tsum->tv_sec++, tsum->tv_usec -= 1000000;
  1108. } */
  1109.  
  1110. tvsub(tdiff, t1, t0)
  1111.     struct timeval *tdiff, *t1, *t0;
  1112. {
  1113.  
  1114.     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
  1115.     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
  1116.     if (tdiff->tv_usec < 0)
  1117.         tdiff->tv_sec--, tdiff->tv_usec += 1000000;
  1118. }
  1119.  
  1120. void
  1121. psabort()
  1122. {
  1123.     extern int abrtflag;
  1124.  
  1125.     abrtflag++;
  1126. }
  1127.  
  1128. pswitch(flag)
  1129.     int flag;
  1130. {
  1131.     extern int proxy, abrtflag;
  1132.     sig_t oldintr;
  1133.     static struct comvars {
  1134.         int connect;
  1135.         char name[MAXHOSTNAMELEN];
  1136.         struct sockaddr_in mctl;
  1137.         struct sockaddr_in hctl;
  1138.         FILE *in;
  1139.         FILE *out;
  1140.         int tpe;
  1141.         int curtpe;
  1142.         int cpnd;
  1143.         int sunqe;
  1144.         int runqe;
  1145.         int mcse;
  1146.         int ntflg;
  1147.         char nti[17];
  1148.         char nto[17];
  1149.         int mapflg;
  1150.         char mi[MAXPATHLEN];
  1151.         char mo[MAXPATHLEN];
  1152.     } proxstruct, tmpstruct;
  1153.     struct comvars *ip, *op;
  1154.  
  1155.     abrtflag = 0;
  1156.     oldintr = signal(SIGINT, psabort);
  1157.     if (flag) {
  1158.         if (proxy)
  1159.             return;
  1160.         ip = &tmpstruct;
  1161.         op = &proxstruct;
  1162.         proxy++;
  1163.     } else {
  1164.         if (!proxy)
  1165.             return;
  1166.         ip = &proxstruct;
  1167.         op = &tmpstruct;
  1168.         proxy = 0;
  1169.     }
  1170.     ip->connect = connected;
  1171.     connected = op->connect;
  1172.     if (hostname) {
  1173.         (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
  1174.         ip->name[strlen(ip->name)] = '\0';
  1175.     } else
  1176.         ip->name[0] = 0;
  1177.     hostname = op->name;
  1178.     ip->hctl = hisctladdr;
  1179.     hisctladdr = op->hctl;
  1180.     ip->mctl = myctladdr;
  1181.     myctladdr = op->mctl;
  1182.     ip->in = cin;
  1183.     cin = op->in;
  1184.     ip->out = cout;
  1185.     cout = op->out;
  1186.     ip->tpe = type;
  1187.     type = op->tpe;
  1188.     ip->curtpe = curtype;
  1189.     curtype = op->curtpe;
  1190.     ip->cpnd = cpend;
  1191.     cpend = op->cpnd;
  1192.     ip->sunqe = sunique;
  1193.     sunique = op->sunqe;
  1194.     ip->runqe = runique;
  1195.     runique = op->runqe;
  1196.     ip->mcse = mcase;
  1197.     mcase = op->mcse;
  1198.     ip->ntflg = ntflag;
  1199.     ntflag = op->ntflg;
  1200.     (void) strncpy(ip->nti, ntin, 16);
  1201.     (ip->nti)[strlen(ip->nti)] = '\0';
  1202.     (void) strcpy(ntin, op->nti);
  1203.     (void) strncpy(ip->nto, ntout, 16);
  1204.     (ip->nto)[strlen(ip->nto)] = '\0';
  1205.     (void) strcpy(ntout, op->nto);
  1206.     ip->mapflg = mapflag;
  1207.     mapflag = op->mapflg;
  1208.     (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
  1209.     (ip->mi)[strlen(ip->mi)] = '\0';
  1210.     (void) strcpy(mapin, op->mi);
  1211.     (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
  1212.     (ip->mo)[strlen(ip->mo)] = '\0';
  1213.     (void) strcpy(mapout, op->mo);
  1214.     (void) signal(SIGINT, oldintr);
  1215.     if (abrtflag) {
  1216.         abrtflag = 0;
  1217. /*        (*oldintr)();*/
  1218.         signal(SIGINT, psabort);
  1219.     }
  1220. }
  1221.  
  1222. jmp_buf ptabort;
  1223. int ptabflg;
  1224.  
  1225. void
  1226. abortpt()
  1227. {
  1228.     printf("\n");
  1229.     (void) fflush(stdout);
  1230.     ptabflg++;
  1231.     mflag = 0;
  1232.     abrtflag = 0;
  1233.     longjmp(ptabort, 1);
  1234. }
  1235.  
  1236. proxtrans(cmd, local, remote)
  1237.     char *cmd, *local, *remote;
  1238. {
  1239.     sig_t oldintr;
  1240.     int secndflag = 0, prox_type, nfnd;
  1241.     extern jmp_buf ptabort;
  1242.     char *cmd2;
  1243.     /*struct*/ fd_set mask;
  1244.     void abortpt();
  1245.  
  1246.     if (strcmp(cmd, "RETR"))
  1247.         cmd2 = "RETR";
  1248.     else
  1249.         cmd2 = runique ? "STOU" : "STOR";
  1250.     if ((prox_type = type) == 0) {
  1251.         if (unix_server && unix_proxy)
  1252.             prox_type = TYPE_I;
  1253.         else
  1254.             prox_type = TYPE_A;
  1255.     }
  1256.     if (curtype != prox_type)
  1257.         changetype(prox_type, 1);
  1258.     if (command("PASV") != COMPLETE) {
  1259.         printf("proxy server does not support third party transfers.\n");
  1260.         return;
  1261.     }
  1262.     pswitch(0);
  1263.     if (!connected) {
  1264.         printf("No primary connection\n");
  1265.         pswitch(1);
  1266.         code = -1;
  1267.         return;
  1268.     }
  1269.     if (curtype != prox_type)
  1270.         changetype(prox_type, 1);
  1271.     if (command("PORT %s", pasv) != COMPLETE) {
  1272.         pswitch(1);
  1273.         return;
  1274.     }
  1275.     if (setjmp(ptabort))
  1276.         goto abort;
  1277.     oldintr = signal(SIGINT, abortpt);
  1278.     if (command("%s %s", cmd, remote) != PRELIM) {
  1279.         (void) signal(SIGINT, oldintr);
  1280.         pswitch(1);
  1281.         return;
  1282.     }
  1283.     sleep(2);
  1284.     pswitch(1);
  1285.     secndflag++;
  1286.     if (command("%s %s", cmd2, local) != PRELIM)
  1287.         goto abort;
  1288.     ptflag++;
  1289.     (void) getreply(0);
  1290.     pswitch(0);
  1291.     (void) getreply(0);
  1292.     (void) signal(SIGINT, oldintr);
  1293.     pswitch(1);
  1294.     ptflag = 0;
  1295.     printf("local: %s remote: %s\n", local, remote);
  1296.     return;
  1297. abort:
  1298.     (void) signal(SIGINT, SIG_IGN);
  1299.     ptflag = 0;
  1300.     if (strcmp(cmd, "RETR") && !proxy)
  1301.         pswitch(1);
  1302.     else if (!strcmp(cmd, "RETR") && proxy)
  1303.         pswitch(0);
  1304.     if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
  1305.         if (command("%s %s", cmd2, local) != PRELIM) {
  1306.             pswitch(0);
  1307.             if (cpend)
  1308.                 abort_remote((FILE *) NULL);
  1309.         }
  1310.         pswitch(1);
  1311.         if (ptabflg)
  1312.             code = -1;
  1313.         (void) signal(SIGINT, oldintr);
  1314.         return;
  1315.     }
  1316.     if (cpend)
  1317.         abort_remote((FILE *) NULL);
  1318.     pswitch(!proxy);
  1319.     if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
  1320.         if (command("%s %s", cmd2, local) != PRELIM) {
  1321.             pswitch(0);
  1322.             if (cpend)
  1323.                 abort_remote((FILE *) NULL);
  1324.             pswitch(1);
  1325.             if (ptabflg)
  1326.                 code = -1;
  1327.             (void) signal(SIGINT, oldintr);
  1328.             return;
  1329.         }
  1330.     }
  1331.     if (cpend)
  1332.         abort_remote((FILE *) NULL);
  1333.     pswitch(!proxy);
  1334.     if (cpend) {
  1335.         FD_ZERO(&mask);
  1336.         FD_SET(fileno(cin), &mask);
  1337.         if ((nfnd = empty(&mask, 10)) <= 0) {
  1338.             if (nfnd < 0) {
  1339.                 perror("abort");
  1340.             }
  1341.             if (ptabflg)
  1342.                 code = -1;
  1343.             lostpeer();
  1344.         }
  1345.         (void) getreply(0);
  1346.         (void) getreply(0);
  1347.     }
  1348.     if (proxy)
  1349.         pswitch(0);
  1350.     pswitch(1);
  1351.     if (ptabflg)
  1352.         code = -1;
  1353.     (void) signal(SIGINT, oldintr);
  1354. }
  1355.  
  1356. reset()
  1357. {
  1358.     /*struct*/ fd_set mask;
  1359.     int nfnd = 1;
  1360.  
  1361.     FD_ZERO(&mask);
  1362.     while (nfnd > 0) {
  1363.         FD_SET(fileno(cin), &mask);
  1364.         if ((nfnd = empty(&mask,0)) < 0) {
  1365.             perror("reset");
  1366.             code = -1;
  1367.             lostpeer();
  1368.         }
  1369.         else if (nfnd) {
  1370.             (void) getreply(0);
  1371.         }
  1372.     }
  1373. }
  1374.  
  1375. char *
  1376. gunique(local)
  1377.     char *local;
  1378. {
  1379.     static char new[MAXPATHLEN];
  1380.     char *cp = rindex(local, '/');
  1381.     int d, count=0;
  1382.     char ext = '1';
  1383.  
  1384.     if (cp)
  1385.         *cp = '\0';
  1386.     d = access(cp ? local : ".", 2);
  1387.     if (cp)
  1388.         *cp = '/';
  1389.     if (d < 0) {
  1390.         fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
  1391.         return((char *) 0);
  1392.     }
  1393.     (void) strcpy(new, local);
  1394.     cp = new + strlen(new);
  1395.     *cp++ = '.';
  1396.     while (!d) {
  1397.         if (++count == 100) {
  1398.             printf("runique: can't find unique file name.\n");
  1399.             return((char *) 0);
  1400.         }
  1401.         *cp++ = ext;
  1402.         *cp = '\0';
  1403.         if (ext == '9')
  1404.             ext = '0';
  1405.         else
  1406.             ext++;
  1407.         if ((d = access(new, 0)) < 0)
  1408.             break;
  1409.         if (ext != '0')
  1410.             cp--;
  1411.         else if (*(cp - 2) == '.')
  1412.             *(cp - 1) = '1';
  1413.         else {
  1414.             *(cp - 2) = *(cp - 2) + 1;
  1415.             cp--;
  1416.         }
  1417.     }
  1418.     return(new);
  1419. }
  1420.  
  1421. abort_remote(din)
  1422. FILE *din;
  1423. {
  1424.     char buf[BUFSIZ];
  1425.     int nfnd;
  1426.     /*struct*/ fd_set mask;
  1427.  
  1428.     /*
  1429.      * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
  1430.      * after urgent byte rather than before as is protocol now
  1431.      */
  1432.     sprintf(buf, "%c%c%c", IAC, IP, IAC);
  1433.     if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
  1434.         perror("abort");
  1435.     fprintf(cout,"%cABOR\r\n", DM);
  1436.     (void) fflush(cout);
  1437.     FD_ZERO(&mask);
  1438.     FD_SET(fileno(cin), &mask);
  1439.     if (din) { 
  1440.         FD_SET(fileno(din), &mask);
  1441.     }
  1442.     if ((nfnd = empty(&mask, 10)) <= 0) {
  1443.         if (nfnd < 0) {
  1444.             perror("abort");
  1445.         }
  1446.         if (ptabflg)
  1447.             code = -1;
  1448.         lostpeer();
  1449.     }
  1450.     if (din && FD_ISSET(fileno(din), &mask)) {
  1451.         while (read(fileno(din), buf, BUFSIZ) > 0)
  1452.             /* LOOP */;
  1453.     }
  1454.     if (getreply(0) == ERROR && code == 552) {
  1455.         /* 552 needed for nic style abort */
  1456.         (void) getreply(0);
  1457.     }
  1458.     (void) getreply(0);
  1459. }
  1460.